package com.coffeeloversupportlibrary.core.data;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.collection.LruCache;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import com.coffeeloversupportlibrary.core.data.http.RetrofitProvider;
import retrofit2.Retrofit;

/**
 * @author puyv
 * @createTime 2021/11/3 20:55
 * @projectName CoffeeLoverSupportLibrary
 * @className DiariesRepository.java
 * @description 统一管理数据源，并提供缓存功能
 */
public class DataRepository implements IDataRepository {
    /**
    * 数据库 RetrofitService 最大缓存数
    */
    public static final int DEFAULT_RETROFIT_SERVICE_MAX_SIZE = 20;
    public static final int DEFAULT_ROOM_DATABASE_MAX_SIZE = 20;
    private volatile static DataRepository INSTANCE = null;
    private Retrofit retrofit;

    /**
    * @date 2021/11/3 21:18
    * @params
    * @return
    * @description RetrofitService 缓存
    */
    private LruCache<String,Object> mRetrofitServiceCache;

    /**
    * @date 2021/11/3 21:18
    * @params
    * @return
    * @description 数据库缓存
    */
    private LruCache<String,Object> mRoomDatabaseCache;


    private DataRepository(Retrofit retrofit) {
       this.retrofit=retrofit;
    }

    /**
    * @date 2021/11/3 21:13
    * @params []
    * @return
    * @description 线程安全的单例模式获取数据仓库对象
    */
    public static DataRepository getInstance() {
        if (INSTANCE==null) {
            synchronized (DataRepository.class) {
                if (INSTANCE==null) {
                    INSTANCE=new DataRepository(RetrofitProvider.getInstance().getRetrofit());
                }
            }
        }
        return INSTANCE;
    }

    /**
    * @date 2021/11/3 21:14
    * @params [service]
    * @return T
    * @description 提供 APIService.class 对象，获取 APIService 动态代理实现类
    */
    @Override
    public <T> T getRetrofitService(@NonNull Class<T> service) {
        if(mRetrofitServiceCache == null){
            mRetrofitServiceCache = new LruCache<>(DEFAULT_RETROFIT_SERVICE_MAX_SIZE);
        }
        if (mRetrofitServiceCache == null) {
            throw new NullPointerException();
        }
        T retrofitService = (T)mRetrofitServiceCache.get(service.getCanonicalName());
        if(retrofitService == null){
            synchronized (mRetrofitServiceCache) {
                if(retrofitService == null){
                    // 线程安全单例模式生成 API 的动态代理
                    retrofitService = retrofit.create(service);
                    mRetrofitServiceCache.put(service.getCanonicalName(),retrofitService);
                }

            }
        }
        return retrofitService;
    }


    /**
    * @date 2021/11/3 21:15
    * @params [database, dbName]
    * @return T
    * @description 获取数据库
    */
    @Override
    public <T extends RoomDatabase> T getRoomDatabase(@NonNull Class<T> database, @Nullable String dbName,@Nullable Context context) {
        if(mRoomDatabaseCache == null){
            mRoomDatabaseCache = new LruCache<>(DEFAULT_ROOM_DATABASE_MAX_SIZE);
        }
        if (mRetrofitServiceCache == null) {
            throw new NullPointerException();
        }
        T roomDatabase = (T)mRoomDatabaseCache.get(database.getCanonicalName());
        if(roomDatabase == null) {
            synchronized (mRoomDatabaseCache) {
                if (roomDatabase == null) {
                    RoomDatabase.Builder<T> builder = Room.databaseBuilder(context.getApplicationContext(), database,dbName);
                    roomDatabase = builder.build();
                    mRoomDatabaseCache.put(database.getCanonicalName(), roomDatabase);
                }
            }
        }
        return roomDatabase;
    }
}
